unit Test;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TfrmTest = class(TForm)
    btnTest: TButton;
    procedure btnTestClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  frmTest: TfrmTest;

implementation

uses
  RTTI,
  Serialization;

{$R *.dfm}

type

  TStorable = class (TSerializable)
    public
      Int : Integer;
      UInt : Cardinal;
      Flt : Extended;
      AStr : AnsiString;
      WStr : String;
      Obj : TStorable;
  end;

procedure FillStorable(const Storable : TStorable);
begin
  Assert(Assigned(Storable));
  With Storable do
  begin
    Randomize; Int := Random(100);
    Randomize; UInt := Random(100);
    Randomize; Flt := Random(1024) / Random(512);
    Randomize; AStr := AnsiString(IntToStr(Random(100500)));
    Randomize; WStr := IntToStr(Random(100500));
  end;
end;

function StorableToString(const Storable : TStorable) : String;
  var
    Ctx : TRTTIContext;
    Fld : TRTTIField;
    L : TStringList;
begin
  L := TStringList.Create;
  For Fld in Ctx.GetType(Storable.ClassType).GetDeclaredFields do
    L.Add(Fld.ToString + ' | ' + Fld.GetValue(Storable).ToString);
  Result := L.Text;
  FreeAndNil(L);
end;

procedure TfrmTest.btnTestClick(Sender: TObject);
  var
    TestObj : TStorable;
    MS : TMemoryStream;
begin
  MS := TMemoryStream.Create;

  TestObj := TStorable.Create;
  FillStorable(TestObj);
  TestObj.Obj := TStorable.Create;
  FillStorable(TestObj.Obj);
  ShowMessage('1st object BEFORE:'#13#10#13#10 + StorableToString(TestObj));
  ShowMessage('2nd object BEFORE:'#13#10#13#10 + StorableToString(TestObj.Obj));

  TestObj.SaveToStream(MS);
  MS.Position := 0;
  FreeAndNil(TestObj.Obj);
  FreeAndNil(TestObj);

  TestObj := TStorable.Create;
  TestObj.Obj := TStorable.Create;
  TestObj.LoadFromStream(MS);
  ShowMessage('1st object AFTER:'#13#10#13#10 + StorableToString(TestObj));
  ShowMessage('2nd object AFTER:'#13#10#13#10 + StorableToString(TestObj.Obj));

  FreeAndNil(TestObj.Obj);
  FreeAndNil(TestObj);
end;

end.
